import json

from dataclasses import fields

from pandas import DataFrame

from common.mydb import SQL
from common.pd import get_tb_data


def json_to_str(data_dict: dict):
    """把json 数据转为字符串"""
    return json.dumps(data_dict)


def str_to_json(data_str: str):
    """把字符串转为json数据"""
    return json.loads(data_str)


def get_data_names(cls):
    """获取数据类的字段名列表"""
    return [field.name for field in fields(cls)]


def get_no_id_col_list(model):
    """
    获取没有id的字段名列表
    """
    return [field.name for field in fields(model)][1:]


def model_to_value_list(model, no_id=True):
    """
    把数据对象转为值列表
    model: 数据对象
    no_id： 设置是否包含id
    """
    col_names = get_data_names(model)
    if no_id:
        col_names = col_names[1:]
    value_list = []
    for col_name in col_names:
        col_value = getattr(model, col_name)
        if "json" in col_name:
            col_value = json_to_str(col_value)
        if "id" in col_name and "once" not in col_name:
            col_value = int(col_value)
        if not col_value:
            col_value = ""
        value_list.append(col_value)
    return value_list


def value_list_to_model(cls, value_list, col_name_list=[]) -> object:
    """
    把数值列表转为model对象
    """
    if not col_name_list:
        col_name_list = get_data_names(cls)
    model = cls()
    for index, col_name in col_name_list:
        if index < len(value_list):
            value = value_list[index]
            if "json" in col_name:
                value = str_to_json(value)

        else:
            vlaue = ""
        setattr(model, col_name, value)

    return model


def values_to_models(cls, values: list, col_name_list=[]) -> list:
    """把多个数据转为数据对象列表"""

    models = []
    if values:
        for value in values:
            models.append(value_list_to_model(cls, value, col_name_list))
    return models


def models_to_values(models, no_id=True):
    """把数据对象转为列表"""
    if models:
        values = []
        for model in models:
            values.append(model_to_value_list(model, no_id=no_id))
        return values


def insert_model(table_name, model):
    """在数据表中增加一条数据"""

    sql = SQL()
    col_name_list = model_to_value_list(model)
    value_list = model_to_value_list(model)
    sql.insert_one(table_name, col_name_list, value_list)


def insert_many(table_name, models):
    """在数据表中增加多条数据"""
    sql = SQL()
    if models:
        col_name_list = get_no_id_col_list(models[0])
        values_list = []
        for model in models:
            value_list = model_to_value_list(model)
            values_list.append(value_list)

        sql.insert_many(table_name, col_name_list, values_list)


def update_one(table_name, model):
    """在数据表中更新一条数据"""
    sql = SQL()
    col_name_list = get_no_id_col_list(model)
    value_list = model_to_value_list(model)
    sql.update_one(table_name, col_name_list, value_list, id=model.id)


def update_many_model(table_name, models):
    """在数据表中更新多条数据"""
    if models:
        col_name_list = get_data_names(models[0])
        values = models_to_values(models=models, no_id=False)

        sql = SQL()
        sql.update_many_by_id(table_name, col_name_list, values)


def df_to_models(df_datas: DataFrame, cls) -> list:
    """把dataframe 转为数据对象"""
    models = []
    if not df_datas.empty:
        row_count, col_count = df_datas.shape
        col_name_list = df_datas.columns.tolist()

        for row_index in range(row_count):
            model = cls()
            for col_name in col_name_list:
                value = df_datas.loc[row_index, col_name]
                if "json" in col_name:
                    value = str_to_json(value)
                setattr(model, col_name, value)
            models.append(model)
    return models


def db_to_models(tb_name, cls, condition=""):
    """把数据表的数据转为数据对象"""
    df_datas = get_tb_data(table_name=tb_name, condition=condition)
    return df_to_models(df_datas, cls)
